package com.nineclock.approve.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nineclock.approve.pojo.ApproveDefinition;
import com.nineclock.approve.resolver.ProcessNodeResolver;
import com.nineclock.approve.resolver.ProcessNodeResolverFactory;
import com.nineclock.approve.service.ActivitiService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Slf4j
@Service
public class ActivitiServiceImpl implements ActivitiService {

    @Autowired
    RepositoryService repositoryService;


    @Override
    public void deployProcessToActiviti(ApproveDefinition definition) {
        //构建模型对象
        BpmnModel bpmnModel = new BpmnModel();

        //创建流程对象
        Process process = new Process();
        //此id对应的是 ACT_RE_PROCDEF 表中  key
        process.setId("process_" + definition.getId());
        process.setName(definition.getName());

        //流程json对象
        String flowJson = definition.getFlowJson();
        //解析成json数组
        JSONArray jsonArray = JSONUtil.parseArray(flowJson);

        this.addNodeAddProcess(process, jsonArray);

        //添加流程对象到模型中
        bpmnModel.addProcess(process);
        //自动布局
        new BpmnAutoLayout(bpmnModel).execute();


        repositoryService.createDeployment().name(definition.getName()).addBpmnModel(definition.getName()+".bpmn", bpmnModel).deploy();
    }

    @Override
    public void dropProcessFromActiviti(ApproveDefinition definition) {
        //根据流程 key 获取流程定义对象
        ProcessDefinition processDefinition =
                repositoryService.createProcessDefinitionQuery().processDefinitionKey("process_" + definition.getId()).singleResult();
        //根据部署id 删除 流程定义
        repositoryService.deleteDeployment(processDefinition.getDeploymentId());
    }

    private void addNodeAddProcess(Process process, JSONArray jsonArray) {
        if(jsonArray.size() > 0){
            for (int i = 0; i < jsonArray.size(); i++) {
                //获取当前节点
                JSONObject currNode = (JSONObject) jsonArray.get(i);
                //下一个节点
                JSONObject nextNode = null;
                if(i < jsonArray.size() - 1){
                   nextNode  = (JSONObject) jsonArray.get(i + 1);
                }

                String type = currNode.getStr("type");
                //根据类型 获取相应类型的 节点解析器
                ProcessNodeResolver nodeResolver = ProcessNodeResolverFactory.getInstance(type);

                nodeResolver.addFlowNodeToActiviti(process, currNode, nextNode);
            }
        }
        
    }
}
